#include "trap.h"
#include "ysyxsoc.h"
#include "riscv.h"
// 0xa0000000 ~ 0xa4000000
void uint8_test (size_t addr_base,size_t len){
    for (size_t i = addr_base; i < addr_base+len; i++)
    {
        outb(i, (uint8_t)(i & 0x000000ff));      
    }    
    for (size_t i = addr_base; i < addr_base+len; i++)
    {
        check(inb(i) == (uint8_t)(i & 0x000000ff));
    }        
}



void uint16_test (size_t addr_base,size_t len){
    for (size_t i = addr_base; i < addr_base+len; i=i+2)
    {
        outw(i, (uint16_t)(i & 0x000000ffff));
    }    
    for (size_t i = addr_base; i < addr_base+len; i=i+2)
    {
        check(inw(i) == (uint16_t)(i & 0x000000ffff));
    }        
}


void uint32_test (size_t addr_base,size_t len){
    for (size_t i = addr_base; i < addr_base+len; i=i+4)
    {
        outl(i, (uint32_t)(i & 0xffffffff));
        check(inl(i) == (uint32_t)(i & 0xffffffff));
    }    
    // for (size_t i = addr_base; i < addr_base+len; i=i+4)
    // {
    //     check(inl(i) == (uint32_t)(i & 0xffffffff));
    // }        
}

// 0xa0000000 ~ 0xa8000000
void unalign_test (size_t addr_base,size_t len){
    for (size_t i = addr_base; i < addr_base+len; i=i+4)
    {
        outb(i,   (uint8_t) (i     & 0x000000ff));   
        outw(i+1, (uint16_t)((i+1) & 0x0000ffff)); 
        check(inb(i) == (uint8_t)(i & 0x000000ff));
        check(inw(i+1) == (uint16_t)((i+1) & 0x0000ffff));
        outw(i+2, (uint16_t)((i+2) & 0x0000ffff));
        check(inw(i+2) == (uint16_t)((i+2) & 0x0000ffff));
    }    
    for (size_t i = addr_base; i < addr_base+len; i=i+4)
    {
        check(inb(i)   == (uint8_t) (i     & 0x000000ff));
        check(inw(i+2) == (uint16_t)((i+2) & 0x0000ffff));
    }        
}




int main() {

 //    uint32_test(SDRAM_ADDR + SDRAM_SIZE / 2 - 0x100, SDRAM_SIZE / 4 + 0x100);
// uint8_test(SDRAM_ADDR + SDRAM_SIZE / 8, SDRAM_SIZE / 4 + 0x10);
    unalign_test(SDRAM_ADDR + SDRAM_SIZE / 4 + SDRAM_SIZE / 2 - 0x100, SDRAM_SIZE / 4 + 0x100);
//    uint16_test(SDRAM_ADDR + SDRAM_SIZE / 4 - 0x10, SDRAM_SIZE / 4 + 0x10);



    for (size_t i = 0; i < 5; i++)
    {
        outl(SDRAM_ADDR + 0x9000 + i * 4, ((long long)i & 0xff8ff8ff));
    }
    for (size_t i = 0; i < 5; i++)
    {
        check(inl(SDRAM_ADDR+0x9000+i*4) == ((long long)i&0xff8ff8ff));
    }



    for (size_t i = 9*1024; i < 20*1024; i++)
    {
        outl(SDRAM_ADDR+i*4,  ((long long)i&0xff8ff8ff));
    }
    for (size_t i = 9*1024; i < 20*1024; i++)
    {
        check(inl(SDRAM_ADDR+i*4) == (i&0xff8ff8ff));
    }
    for (size_t i = 2*1024*1024; i <2*1024*1024+4096; i++)
    {
        outb(SDRAM_ADDR+i*4+0,  0x09);
        outw(SDRAM_ADDR+i*4+2,  0xf912);
        outb(SDRAM_ADDR+i*4+1,  0x34); 
        check(inl(SDRAM_ADDR+i*4) == 0xf9123409);  
    }
    for (size_t i = 2*1024*1024; i <2*1024*1024+4096; i++)
    {
        check(inl(SDRAM_ADDR+i*4) == 0xf9123409);  
    }


    return 0;
}
